<?php

class MsggMail
{
    use util_array;
    const MAIL_FROM_NAME = 'BaiShanCloud';
    const MAIL_TITLE = 'Mail From BaiShanCloud';


    public static function execute($params = array(), $channelConfs = [])
    {
        //gen result
        $result = array('code' => 0, 'msg' => '', 'detail' => array());
        try {
            //check address and make sure it is a array and not empty
            $params['address'] = empty($params['address']) ? array() : (is_array($params['address']) ? $params['address'] : array($params['address']));
            foreach ($params['address'] as $i => $address) {
                if (!filter_var($address, FILTER_VALIDATE_EMAIL)) {
                    unset($params['address'][$i]);
                }
            }
            if (empty($params['address'])) {
                throw new Exception(MsggItem::ERROR_MSG_ITEM_PARAMS_INVALID . ':mail address is invalid', MsggItem::ERROR_CODE_ITEM_PARAMS_INVALID);
            }
            //check content
            if (empty($params['content'])) {
                throw new Exception(MsggItem::ERROR_MSG_ITEM_PARAMS_INVALID . ':mail content is invalid', MsggItem::ERROR_CODE_ITEM_PARAMS_INVALID);
            }
            //check mail from name
            $params['from'] = empty($params['from']) ? self::MAIL_FROM_NAME : $params['from'];
            //check mail title
            $params['title'] = empty($params['title']) ? self::MAIL_TITLE : $params['title'];
            //begin send by channel conf
            $lastResult = false;
            foreach ($channelConfs as $i => $channelConf) {
                $channelResult = MsggSmtp::mail($params, $channelConf);
                $channelName = implode('_', array(MsggItem::TYPE_MAIL, (empty($channelConf['name']) ? 'Channel' . $i : $channelConf['name'])));
                $result['detail'][$channelName] = $channelResult;
                //add log
                $attributes = array(
                    'type'=>MsggItem::TYPE_MAIL,
                    'params' => $params,
                    'result' => $channelResult,
                    'channel' => $channelName,
                    'status'=>$channelResult['code']==0?MsggItem::STATUS_SUCCESS:MsggItem::STATUS_FAILURE,
                    'conf' => $channelConf,
                );
                $log = MsggChannelLog::build($attributes);
                $result['logs'][] = $log;


                if (isset($channelResult['code']) && ($channelResult['code'] == 0)) {
                    $result['ext'] = empty($channelResult['ext']) ? array() : $channelResult['ext'];
                    $lastResult = true;
                    break;
                }
            }
            if (!$lastResult) {
                throw new Exception(MsggItem::ERROR_MSG_GATEWAY_FAILURE, MsggItem::ERROR_CODE_GATEWAY_FAILURE);
            }
        } catch (Exception $e) {
            $result['code'] = MsggItem::ERROR_CODE_GATEWAY_FAILURE;
            $result['msg'] = $e->getMessage();
        }
        return $result;
    }

    public static function mapCodeStatus($channelClass, $code)
    {
        return ($code==0&&$channelClass==MsggSmtp::class)?MsggItem::STATUS_SUCCESS:MsggItem::STATUS_FAILURE;
    }

    public static function refreshStatus(MsggItem $item)
    {
        $status = MsggItem::STATUS_FAILURE;
        if ($item != null && !empty($channelLogs =$item->msgChannelLogs)) {
            $channelLog =@end($channelLogs);
            $config = json_decode($channelLog->conf, true);
            $class = self::util_array_get($config, 'class', null);
            $status=$channelLog->status;
            if ($class) {
                if (class_exists($class)) {
                    $available_method = array();
                    foreach (get_class_methods($class) as $method) {
                        $available_methods[strtolower($method)] = $method;
                    }
                    if (empty($available_methods['refreshStatus'])) {
                        Yii::log('refreshStatus method  not exists  in class ' . $class, CLogger::LEVEL_ERROR, 'msggcall.refreshStatus');
                    } else {
                        $ext_status = call_user_func_array(array($class, 'refreshStatus'), array($channelLog));
                        if (!empty($ext_status)) {
                            $channelLog->ext_status = $ext_status;
                            $channelLog->save();
                        }
                    }
                } else {
                    Yii::log('calss not exists ' . $class . ' log id ' . $channelLog->id, CLogger::LEVEL_ERROR, 'msggcall.refreshStatus');
                }
            }
        }
        return $status;
    }



}
